/*
 * listas.c
 */

#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <strings.h>
#include <pthread.h>
#include "listas.h"


//Variables Globales

/* mutex */
pthread_mutex_t mutexListaCache = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexListaEnviar = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexListaServidores = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexListaEncontrados = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexListaQuerys = PTHREAD_MUTEX_INITIALIZER;


int newLista(int tipo, lista *l ) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'newLista() de listas.c --\n");
	//return 1;
#endif
	l->tam = 0;
	l->inicio = NULL;
	l->fin = NULL;
	l->actual = NULL;
	l->tipo = tipo;
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Fin en 'newLista() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int insertLista( lista *l, char * key, void * datos ) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'insertLista() de listas.c --\n");
	//return 1;
#endif
	nodo * new;
	new = malloc( sizeof( struct nodo ) );
	new->key = strdup( key );
	new->datos = datos;
	new->next = NULL;
	if (l->inicio == NULL){
		l->inicio = new;
	}else{
		l->fin->next = new;
	}
	l->fin = new;
	l->tam++;
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Fin en 'insertLista() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int resetLista( lista *l ) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'resetLista() de listas.c --\n");
	//return 1;
#endif
	l->actual = l->inicio;
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Fin en 'resetLista() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

struct nodo * nextLista( lista *l) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'nextLista() de listas.c --\n");
	//return 1;
#endif
	struct nodo * aux;
	aux = l->actual;
	if( aux != NULL ) {
		l->actual = aux->next;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Fin en 'nextLista() de listas.c, salida=estructura nodo --\n");
	//return 1;
#endif
	return aux;
}

struct nodo * buscarNodo(char * key, lista *l ) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'buscarNodo() de listas.c --\n");
	//return 1;
#endif
	nodo * aux;
	if( l->tam == 0 ) {
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'buscarNodo() de listas.c, salida=NULL --\n");
		//return 1;
#endif
		return NULL;
	}
	aux = l->inicio;
	while( aux != NULL ) {
		if( strcmp( aux->key, key ) == 0 ) {
#ifdef DEBUG_LISTAS
			fprintf(stderr,"\t -2-Fin en 'buscarNodo() de listas.c, salida=estructura de nodo --\n");
			//return 1;
#endif
			return aux;
		}
		aux = aux->next;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -3-Fin en 'buscarNodo() de listas.c, salida=NULL --\n");
	//return 1;
#endif
	return NULL;
}

struct nodo * primerNodo( lista *l ){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'primerNodo() de listas.c --\n");
	//return 1;
#endif
	nodo * aux;

	if( l->tam == 0 ) {
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'primerNodo() de listas.c, salida=NULL --\n");
		//return 1;
#endif
		return NULL;
	}else{
		aux = l->inicio;
		l->inicio = aux->next;
		l->tam--;
		if( l->tam == 1 ) {
			l->fin = NULL;
		}
		if(l->tam == 0){
			l->inicio = NULL;
			l->fin = NULL;
			l->actual = NULL;
		}
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -2-Fin en 'primerNodo() de listas.c, salida=estructura de Nodo --\n");
	//return 1;
#endif
	return aux;
}


int eliminarNodo(char * key,  lista *l ) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'eliminarNodo() de listas.c --\n");
	//return 1;
#endif
	nodo * ant, *act, *sig, *aux;

	if( l->tam == 0 ) {
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'eliminarNodo() de listas.c, salida=%i --\n", B_FALSE);
		//return 1;
#endif
		return B_FALSE;
	}
	// Si solo hay un elemento
	if( l->tam==1){
		if( strcmp( l->inicio->key , key ) == 0 ){
			free(l->inicio);
			l->inicio = NULL;
			l->actual = NULL;
			l->fin = NULL;
			l->tam = 0;
#ifdef DEBUG_LISTAS
			fprintf(stderr,"\t -2-Fin en 'eliminarNodo() de listas.c, salida=%i --\n", B_TRUE);
			//return 1;
#endif
			return B_TRUE;
		}else{
#ifdef DEBUG_LISTAS
			fprintf(stderr,"\t -3-Fin en 'eliminarNodo() de listas.c, salida=%i --\n", B_FALSE);
			//return 1;
#endif
			return B_FALSE;
		}
	}

	if( strcmp( l->inicio->key , key ) == 0 ){
		aux=l->inicio->next;
		free(l->inicio);
		l->inicio = aux->next;
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -4-Fin en 'eliminarNodo() de listas.c, salida=%i --\n", B_TRUE);
		//return 1;
#endif
		return B_TRUE;
	}
	ant = l->inicio;
	act = ant->next;
	sig = act->next;


	while( sig->next != NULL ) {
		if( strcmp( act->key, key ) == 0 ) {
			if(act==l->fin){
				l->fin=ant;
			}
			ant->next=sig;
			free( act );
#ifdef DEBUG_LISTAS
			fprintf(stderr,"\t -5-Fin en 'eliminarNodo() de listas.c, salida=%i --\n", B_TRUE);
			//return 1;
#endif
			return B_TRUE;
		}
		ant = act;
		act = sig;
		sig=sig->next;;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -6-Fin en 'eliminarNodo() de listas.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
	return B_FALSE;
}

int freeLista( lista *l ) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'freeLista() de listas.c --\n");
	//return 1;
#endif
	nodo *act, *sig;

	if( l->tam == 0 ) {
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'freeLista() de listas.c, salida=%i --\n", B_FALSE);
		//return 1;
#endif
		return B_TRUE;
	}else if( l->tam == 1 ) {
		free(l->inicio);
	}else{

		act = l->inicio;
		sig = act->next;

		while( sig != NULL ) {
			free( act );
			l->tam--;
			act=sig;
			sig = sig->next;
		}
	}
	l->inicio = NULL;
	l->fin = NULL;
	l->actual = NULL;
	l->tam=0;
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -2-Fin en 'freeLista() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int inicializarListas() {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'inicializarListas() de listas.c --\n");
	//return 1;
#endif
	newLista( SERVENT, &listaCache );
	newLista( MENSAJE, &listaEnviar );
	newLista( QUERY_ID, &listaQuerys );
	newLista( SERVENT, &listaServidores );
	newLista( QUERY, &listaEncontrados );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'inicializarListas() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int freeListas() {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'freeListas() de listas.c --\n");
	//return 1;
#endif
	struct serventNode *aux;
	aux = getNodoConectado();
	while( aux != NULL ) {
		close( aux->socket_fd );
		aux = getNodoConectado();
	}
	pthread_mutex_lock( &mutexListaQuerys );
	freeLista( &listaQuerys );
	pthread_mutex_unlock( &mutexListaQuerys );
	pthread_mutex_destroy(&mutexListaQuerys);
	pthread_mutex_lock( &mutexListaEnviar );
	freeLista( &listaEnviar );
	pthread_mutex_unlock( &mutexListaEnviar );
	pthread_mutex_destroy(&mutexListaEnviar);
	pthread_mutex_lock( &mutexListaCache );
	freeLista( &listaCache );
	pthread_mutex_unlock( &mutexListaCache );
	pthread_mutex_destroy(&mutexListaCache);
	pthread_mutex_lock( &mutexListaEncontrados );
	freeLista( &listaEncontrados );
	pthread_mutex_unlock( &mutexListaEncontrados );
	pthread_mutex_destroy(&mutexListaEncontrados);
	pthread_mutex_lock( &mutexListaServidores );
	freeLista( &listaServidores );
	pthread_mutex_unlock( &mutexListaServidores );
	pthread_mutex_destroy(&mutexListaServidores);
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'freeListas() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int insertMessage(struct message *id) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'resetLista() de listas.c --\n");
	//return 1;
#endif
	int sal=0;
	pthread_mutex_lock( &mutexListaEnviar );
	sal=insertLista(&listaEnviar, id->header->GUID, (void *)id );
	pthread_mutex_unlock( &mutexListaEnviar );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'eliminarNodo() de listas.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

struct message *extractMessage (){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'extractMessage() de listas.c --\n");
	//return 1;
#endif
	struct message * sal=NULL;
	nodo * nodo_aux=NULL;
	pthread_mutex_lock( &mutexListaEnviar );
	nodo_aux = primerNodo( &listaEnviar );
	pthread_mutex_unlock( &mutexListaEnviar );
	if( nodo_aux != NULL ) {
		sal = (struct message *) nodo_aux->datos;
	}else{
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'extractMessage() de listas.c, salida=NULL --\n");
		//return 1;
#endif
		return NULL;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -2-Fin en 'extractMessage() de listas.c, salida=estructura de mensaje --\n");
	//return 1;
#endif
	return sal;
}

int insertarQueryId (struct queryId *id){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'insertarQueryId() de listas.c --\n");
	//return 1;
#endif
	int sal=0;
	pthread_mutex_lock( &mutexListaQuerys );
	sal=insertLista( &listaQuerys, id->id, (void *)id );
	pthread_mutex_unlock( &mutexListaQuerys );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'insertarQueryId() de listas.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

struct queryId *buscarQueryId ( char *id ){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'buscarQueryId() de listas.c --\n");
	//return 1;
#endif
	nodo *aux=NULL;
	struct queryId *sal=NULL;
	pthread_mutex_lock( &mutexListaQuerys );
	aux = buscarNodo(id, &listaQuerys );
	pthread_mutex_unlock( &mutexListaQuerys );
	if( aux != NULL ) {
		sal = (struct queryId *)aux->datos;
	}else{
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'buscarQueryId() de listas.c, salida=NULL --\n");
		//return 1;
#endif
		return NULL;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -2-Fin en 'buscarQueryId() de listas.c, salida=estructura de QueryID --\n");
	//return 1;
#endif
	return sal;
}



int borrarQueryId (char *id){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'borrarQueryId() de listas.c --\n");
	//return 1;
#endif
	int sal=0;
	pthread_mutex_lock( &mutexListaQuerys );
	sal = eliminarNodo(id, &listaQuerys );
	pthread_mutex_unlock( &mutexListaQuerys );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'borrarQueryId() de listas.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

int insertNodoCache(struct serventNode *id ){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'insertNodoCache() de listas.c --\n");
	//return 1;
#endif
	char idSN[16];
	int sal=0;
	sprintf( idSN, "%d", id->socket_fd );
	pthread_mutex_lock( &mutexListaCache );
	sal = insertLista( &listaCache, idSN, (void *)id );
	pthread_mutex_unlock( &mutexListaCache );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'insertNodoCache() de listas.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

int mostrarNodosQuerys (){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'mostrarNodosQuerys() de listas.c --\n");
	//return 1;
#endif
	struct serventNode *aux=NULL;
	struct sockaddr_in *addr=NULL;
	char ip[INET_ADDRSTRLEN];
	nodo * act;
	pthread_mutex_lock( &mutexListaCache );
	primerNodo( &listaCache );
	act = nextLista( &listaCache );
	while (act != NULL){
		aux = (struct serventNode *)act->datos;
		addr = (struct sockaddr_in *)&aux->addr;
		bzero (ip, INET_ADDRSTRLEN );
		inet_ntop(AF_INET, &addr->sin_addr,ip,sizeof(ip));
		printf("%s:%d\n", ip,ntohs(addr->sin_port));
		act = nextLista( &listaCache );
	}
	pthread_mutex_unlock( &mutexListaCache );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'mostrarNodosQuerys() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}


struct serventNode * getNodoCache(){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'getNodoCache() de listas.c --\n");
	//return 1;
#endif
	nodo * aux=NULL;
	struct serventNode * sal=NULL;
	pthread_mutex_lock( &mutexListaCache );
	aux = primerNodo( &listaCache);
	pthread_mutex_unlock( &mutexListaCache );
	if( aux != NULL ) {
		sal = (struct serventNode *)aux->datos;
	}else{
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'getNodoCache() de listas.c, salida=NULL --\n");
		//return 1;
#endif
		return NULL;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -2-Fin en 'getNodoCache() de listas.c, salida=estructura ServenNode --\n");
	//return 1;
#endif
	return sal;
}

int borrarNodoCache ( unsigned int id ) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'borrarNodoCache() de listas.c --\n");
	//return 1;
#endif
	char idSN[16];
	int sal=-1;
	sprintf(idSN, "%d", id );
	pthread_mutex_lock( &mutexListaCache );
	sal = eliminarNodo( idSN, &listaCache );
	pthread_mutex_unlock( &mutexListaCache );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'borrarNodoCache() de listas.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

int mostrarNodosCache () {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'mostrarNodosCache() de listas.c --\n");
	//return 1;
#endif
	struct serventNode *aux=NULL;
	struct sockaddr_in *addr=NULL;
	char ip[INET_ADDRSTRLEN];
	nodo * act;
	pthread_mutex_lock( &mutexListaCache );
	primerNodo( &listaCache );
	act = nextLista( &listaCache );
	while (act != NULL){
		aux = (struct serventNode *)act->datos;
		addr = (struct sockaddr_in *)&aux->addr;
		bzero (ip, INET_ADDRSTRLEN );
		inet_ntop(AF_INET, &addr->sin_addr,ip,sizeof(ip));
		printf("%s:%d\n", ip,ntohs(addr->sin_port));
		act = nextLista( &listaCache );
	}
	pthread_mutex_unlock( &mutexListaCache );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'mostrarNodosCache() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}


int insertNodeConectado(struct serventNode *id) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'insertNodeConectado() de listas.c --\n");
	//return 1;
#endif
	char aux[16];
	int sal=0;
	sprintf( aux, "%d", id->socket_fd );
	pthread_mutex_lock( &mutexListaServidores );
	sal = insertLista( &listaServidores, aux, (void *)id );
	pthread_mutex_unlock( &mutexListaServidores );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'insertNodeConectado() de listas.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

struct serventNode * getNodoConectado () {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'getNodoConectado() de listas.c --\n");
	//return 1;
#endif
	nodo * aux;
	struct serventNode *sal=NULL;
	pthread_mutex_lock( &mutexListaServidores );
	aux = primerNodo( &listaServidores );
	pthread_mutex_unlock( &mutexListaServidores );
	if( aux != NULL ) {
		sal = (struct serventNode *)aux->datos;
	}else{
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'getNodoConectado() de listas.c, salida=NULL --\n");
		//return 1;
#endif
		return NULL;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -2-Fin en 'getNodoConectado() de listas.c, salida=estructura serventNode --\n");
	//return 1;
#endif
	return sal;
}

int borrarNodoConectado (unsigned int id) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'borrarNodoConectado() de listas.c --\n");
	//return 1;
#endif
	char aux[16];
	int sal;
	sprintf(aux, "%d", id );
	pthread_mutex_lock( &mutexListaServidores );
	sal = eliminarNodo(aux, &listaServidores);
	pthread_mutex_unlock( &mutexListaServidores );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'borrarNodoConectado() de listas.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

int mostrarNodosConectados (){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'mostrarNodosConectados() de listas.c --\n");
	//return 1;
#endif
	struct serventNode *act;
	struct sockaddr_in *addr;
	char ip[INET_ADDRSTRLEN];
	nodo * aux;
	pthread_mutex_lock( &mutexListaServidores );
	primerNodo( &listaServidores );
	aux = nextLista( &listaServidores );
	while (aux != NULL){
		act = (struct serventNode *)aux->datos;
		addr = (struct sockaddr_in *)&act->addr;
		bzero (ip, INET_ADDRSTRLEN );
		inet_ntop(AF_INET, &addr->sin_addr,ip,sizeof(ip));
		printf("%s:%d\n", ip,ntohs(addr->sin_port));
		aux = nextLista( &listaServidores );
	}
	pthread_mutex_unlock( &mutexListaServidores );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'mostrarNodosConectados() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}


struct serventNode * firstNodoConectado(){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'firstNodoConectado() de listas.c --\n");
	//return 1;
#endif
	struct serventNode * sal=NULL;
	nodo * aux;

	pthread_mutex_lock( &mutexListaServidores );
	primerNodo( &listaServidores );
	aux = nextLista( &listaServidores );
	pthread_mutex_unlock( &mutexListaServidores );
	if( aux != NULL ) {
		sal = (struct serventNode *)aux->datos;
	}else{
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'firstNodoConectado() de listas.c, salida=NULL --\n");
		//return 1;
#endif
		return NULL;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -2-Fin en 'firstNodoConectado() de listas.c, salida=estructura serventNode --\n");
	//return 1;
#endif
	return sal;
}

struct serventNode * nextNodoConectado(struct serventNode *id ) {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'nextNodoConectado() de listas.c --\n");
	//return 1;
#endif
	char aux[16];
	nodo * act=NULL;
	struct serventNode * sal=NULL;

	if( id == NULL ) {
		return NULL;
	}
	sprintf( aux, "%d", id->socket_fd );
	pthread_mutex_lock( &mutexListaServidores );
	act = buscarNodo(aux, &listaServidores );
	act = act->next;
	pthread_mutex_unlock( &mutexListaServidores );
	if( act != NULL ) {
		sal = (struct serventNode *)act->datos;
	}else{
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'nextNodoConectado() de listas.c, salida=NULL --\n");
		//return 1;
#endif
		return NULL;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -2-Fin en 'nextNodoConectado() de listas.c, salida=estructura serventNode --\n");
	//return 1;
#endif
	return sal;
}



int freeEncontrados() {
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'freeEncontrados() de listas.c --\n");
	//return 1;
#endif
	pthread_mutex_lock( &mutexListaEncontrados );
	freeLista( &listaEncontrados );
	pthread_mutex_unlock( &mutexListaEncontrados );
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'freeEncontrados() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int mostrarListaEncontrados (){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'mostrarListaEncontrados() de listas.c --\n");
	//return 1;
#endif
	struct fileQuery *aux;
	nodo *sal;
	struct sockaddr_in *addr;
	char ip[INET_ADDRSTRLEN];

	primerNodo( &listaEncontrados);
	sal = nextLista( &listaEncontrados);

	while (sal != NULL){
		aux = (struct fileQuery *)sal->datos;
		addr = (struct sockaddr_in *) &aux->address;
		inet_ntop(AF_INET, &addr->sin_addr,ip,sizeof(ip));
		if (aux->tam > 1048576){
			printf("%d) %s \n\t%s:%d\n\t%.2fM\n",aux->id, aux->nombreArchivo,ip,ntohs(addr->sin_port),aux->tam/1048576.0);
		}else{
			printf("%d) %s \n\t%s:%d\n\t%.2fK\n",aux->id, aux->nombreArchivo,ip,ntohs(addr->sin_port),aux->tam/1024.0);
		}
		sal = nextLista( &listaEncontrados);
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'mostrarListaEncontrados() de listas.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int insertEncontrado (struct fileQuery *id ){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'insertEncontrado() de listas.c --\n");
	//return 1;
#endif
	int sal;
	char num[12];
	sprintf( num, "%d", id->id );
	sal = insertLista( &listaEncontrados, num, (void *)id);
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -1-Fin en 'insertEncontrado() de listas.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

struct fileQuery *buscarEncontrado (int id){
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t --Inicio en 'buscarEncontrado() de listas.c --\n");
	//return 1;
#endif
	char num[12];
	nodo *aux;
	struct fileQuery *sal;
	aux = NULL;
	sal=NULL;
	sprintf( num, "%d", id );
	aux = buscarNodo(num, &listaEncontrados );
	if( aux != NULL ) {
		sal = (struct fileQuery *) aux->datos;
	}else{
#ifdef DEBUG_LISTAS
		fprintf(stderr,"\t -1-Fin en 'buscarEncontrado() de listas.c, salida=NULL --\n");
		//return 1;
#endif
		return NULL;
	}
#ifdef DEBUG_LISTAS
	fprintf(stderr,"\t -2-Fin en 'buscarEncontrado() de listas.c, salida=estructura fileQuery --\n");
	//return 1;
#endif
	return sal;
}
